//
//  HSYWaterWaveView.m
//  高仿暴走斗图
//
//  Created by key on 16/9/26.
//  Copyright © 2016年 huangsongyao. All rights reserved.
//

#import "HSYWaterWaveView.h"
#import "CAShapeLayer+WavePath.h"

#define WAVE_CYCLE_OFFSET           1.29f
#define WAVE_VARIABLE_OFFSET        1.6f
#define WAVE_UP_GROWTH_OFFFSET      0.85f
#define WAVE_SPEED_OFFSET           0.4f
#define WAVE_INCREASE_OFFSET        0.001f
#define WAVE_AMPLITUDE_OFFSET       5.0f
#define WAVE_UP_MAX_PERCENT_OFFSET  0.15f

#define MAX_VALUE                   1.0f
#define MIN_VALUE                   0.0f

@interface HSYWaterWaveView ()

@property (nonatomic, strong) CADisplayLink *waveDisplaylink;       //水波描点的计时锁
@property (nonatomic, strong) CAShapeLayer  *firstWaveLayer;        //第一层外围水波
@property (nonatomic, strong) CAShapeLayer  *secondWaveLayer;       //第二层内围水波

@property (nonatomic, assign) CGFloat variable;                     //可变参数，用于模拟波纹
@property (nonatomic, assign, readonly) BOOL increase;              //增减变化
@property (nonatomic, assign) CGFloat offsetX;                      //波浪x位移
@property (nonatomic, assign) CGFloat currentWavePointY;            //当前波浪上至高度Y
@property (nonatomic, assign) CGFloat waveAmplitude;                //波纹振幅
@property (nonatomic, assign) CGFloat waveCycle;                    //波纹周期
@property (nonatomic, assign) CGFloat waterWaveHeight;              //水波高度
@property (nonatomic, assign) CGFloat waterWaveWidth;               //水波宽度

@property (nonatomic, assign) kWaterWaveAnimationType animateType;  //先上升，后下降

@end

@implementation HSYWaterWaveView

- (instancetype)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame]) {
        [self setup];
    }
    return self;
}

- (void)setup
{
    self.waterWaveHeight = self.viewHeight/2;                                                           //给予水波初始高度
    self.waterWaveWidth = self.viewWidth;                                                               //给予水波初始宽度
    
    _firstWaveColor = [UIColor colorWithRed:223/255.0 green:83/255.0 blue:64/255.0 alpha:1];            //给予水波内道波纹的颜色
    _secondWaveColor = [UIColor colorWithRed:236/255.0f green:90/255.0f blue:66/255.0f alpha:1];        //给予水波外道波纹的颜色
    _upMaxPercent = WAVE_UP_MAX_PERCENT_OFFSET;
    
    self.waveUpGrowth = WAVE_UP_GROWTH_OFFFSET;                                                         //给予水波当前上升速度
    self.waveSpeed = WAVE_SPEED_OFFSET;                                                                 //给予水波当前移动速度
    [self reset];                                                                                       //给予默认的初始设置
    
    if (self.waterWaveWidth > MIN_VALUE) {
        self.waveCycle =  WAVE_CYCLE_OFFSET * M_PI / self.waterWaveWidth;                               //给予水波初始波纹周期
    }
    
    if (self.currentWavePointY <= MIN_VALUE) {
        self.currentWavePointY = self.viewHeight;                                                       //给予水波当前上升至的高度
    }
    
    if (!self.firstWaveLayer) {                                                                         //初始化内道波纹
        self.firstWaveLayer = [CAShapeLayer layer];
        self.firstWaveLayer.fillColor = self.firstWaveColor.CGColor;
        [self.layer addSublayer:self.firstWaveLayer];
    }
    
    if (!self.secondWaveLayer) {                                                                        //初始化外道波纹
        self.secondWaveLayer = [CAShapeLayer layer];
        self.secondWaveLayer.fillColor = self.secondWaveColor.CGColor;
        [self.layer addSublayer:self.secondWaveLayer];
        
    }
}

- (void)reset
{
    self.currentWavePointY = self.viewHeight;                                                           //给予水波当前位置，0表示水波当前处于上升期最底部
    self.variable = WAVE_VARIABLE_OFFSET;                                                               //给予用于模拟波纹用的
    self.offsetX = MIN_VALUE;                                                                           //给予水波初始偏移量
    _increase = NO;                                                                                     //标示位
}

- (void)dealloc
{
    [self reset];
}

#pragma mark - Setter

- (void)setWaveSpeed:(CGFloat)waveSpeed
{
    NSParameterAssert(!(waveSpeed < MIN_VALUE || waveSpeed > M_PI));                 //[0, M_PI]
    _waveSpeed = waveSpeed;
}

- (void)setWaveUpGrowth:(CGFloat)waveUpGrowth
{
    NSParameterAssert(!(waveUpGrowth < MIN_VALUE || waveUpGrowth > MAX_VALUE));      //[0, 1]
    _waveUpGrowth = waveUpGrowth;
}

- (void)setUpMaxPercent:(CGFloat)upMaxPercent
{
    NSParameterAssert(!(upMaxPercent <= MIN_VALUE || upMaxPercent > MAX_VALUE));     //[0, 1]
    _upMaxPercent = upMaxPercent;
}

- (void)setFirstWaveColor:(UIColor *)firstWaveColor
{
    _firstWaveColor = firstWaveColor;
    _firstWaveLayer.fillColor = firstWaveColor.CGColor;
}

- (void)setSecondWaveColor:(UIColor *)secondWaveColor
{
    _secondWaveColor = secondWaveColor;
    _secondWaveLayer.fillColor = secondWaveColor.CGColor;
}

#pragma mark - Operation

- (void)wave
{
    if (self.waveDisplaylink) {
        [self stop];
    }
    self.animateType = kWaterWaveAnimationTypeShow;
    self.waveDisplaylink = [CADisplayLink displayLinkWithTarget:self selector:@selector(currentWave:)];
    [self.waveDisplaylink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
}

- (void)stop
{
    [self reset];
    if(!self.waveDisplaylink) {
        return;
    }
    [self.waveDisplaylink invalidate];
    self.waveDisplaylink = nil;
    self.animateType = kWaterWaveAnimationTypeHide;
}

- (void)waveReset
{
    [self stop];
    [self reset];
    if (self.firstWaveLayer) {
        [self.firstWaveLayer removeFromSuperlayer];
        self.firstWaveLayer = nil;
    }
    if (self.secondWaveLayer) {
        [self.secondWaveLayer removeFromSuperlayer];
        self.firstWaveLayer = nil;
    }
}

- (void)removeFromParentView
{
    [self reset];
    [self removeFromSuperview];
}

#pragma mark - Tracing Point

- (CGFloat)amplitude
{
    if (self.increase) {
        self.variable += WAVE_INCREASE_OFFSET;
    } else {
        self.variable -= WAVE_INCREASE_OFFSET;
    }
    _increase = [self updateIncreaseStatusForVariable:self.variable];
    return (WAVE_AMPLITUDE_OFFSET*self.variable);
}

- (BOOL)updateIncreaseStatusForVariable:(CGFloat)variable
{
    if (variable <= MAX_VALUE) {
        return YES;
    } else if (variable >= WAVE_VARIABLE_OFFSET) {
        return NO;
    }
    return NO;
}

- (void)currentWave:(CADisplayLink *)displayLink
{
    self.waveAmplitude = [self amplitude];
    if (self.animateType == kWaterWaveAnimationTypeShow && self.currentWavePointY > (2 *self.waterWaveHeight *(1-self.upMaxPercent))) {
        self.currentWavePointY -= self.waveUpGrowth;    //波浪高度未到指定高度 继续上涨
    } else if (self.animateType == kWaterWaveAnimationTypeHide && self.currentWavePointY < 2 * self.waterWaveHeight) {
        self.currentWavePointY += self.waveUpGrowth;    //波浪从最高点开始下降
        
    } else if (self.animateType == kWaterWaveAnimationTypeHide && self.currentWavePointY == 2 * self.waterWaveHeight) {
        [self stop];
        [self removeFromParentView];
    } else {
        [self reset];                                   //重置高度
    }
    
    self.offsetX += self.waveSpeed;                     //波浪位移
    [self updateCurrentWaveLayerPath];                  //重新划线
}

- (void)updateCurrentWaveLayerPath
{
    [self.firstWaveLayer updateWavePathForParameter:@{
                                                      
                                                      @(kWavePathParameterTypeWaveCurrentY)     : @(self.currentWavePointY),
                                                      @(kWavePathParameterTypeWaveWidth)        : @(self.waterWaveWidth),
                                                      @(kWavePathParameterTypeWaveCycle)        : @(self.waveCycle),
                                                      @(kWavePathParameterTypeWaveOffsetX)      : @(self.offsetX),
                                                      @(kWavePathParameterTypeWaveInViewHeight) : @(self.viewHeight),
                                                      @(kWavePathParameterTypeWaveAmplitude)    : @(self.waveAmplitude),
                                                      @(kWavePathParameterTypeWaveFunction)     : @(kWavePathFunctionTypeSin),
                                                      
                                                      }wavePathcompleted:^(CGMutablePathRef path) {
                                                          
                                                      }];
    [self.secondWaveLayer updateWavePathForParameter:@{
                                                      
                                                      @(kWavePathParameterTypeWaveCurrentY)     : @(self.currentWavePointY),
                                                      @(kWavePathParameterTypeWaveWidth)        : @(self.waterWaveWidth),
                                                      @(kWavePathParameterTypeWaveCycle)        : @(self.waveCycle),
                                                      @(kWavePathParameterTypeWaveOffsetX)      : @(self.offsetX),
                                                      @(kWavePathParameterTypeWaveInViewHeight) : @(self.viewHeight),
                                                      @(kWavePathParameterTypeWaveAmplitude)    : @(self.waveAmplitude),
                                                      @(kWavePathParameterTypeWaveFunction)     : @(kWavePathFunctionTypeCos),
                                                       
                                                      }wavePathcompleted:^(CGMutablePathRef path) {
                                                          
                                                      }];
}

@end

